/*
 * Copyright (C) 2008 Matt Falkoski
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.falko.android.raven.settings;

import android.content.Context;
import android.content.res.TypedArray;
import android.preference.Preference;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;

import com.falko.android.raven.R;

/**
 * This is sloppy and poorly written ... but it gets the job done
 * 
 * @author matt
 * 
 */
public class SpriteOptionChooserPreference extends Preference implements
		OnSeekBarChangeListener, OnCheckedChangeListener {

	private final String TAG = getClass().getName();

	private String checkBoxText_ = "error";
	private CheckBox randomCheckBox_;

	private SeekBar seekBar_;
	private String seekBarText_ = "error";
	private int seekBarOneMin_;
	private int seekBarOneMax_;

	private SeekBar seekBarMax_;
	private String seekBarMaxText_ = "error";
	private int seekBarMaxMin_;
	private int seekBarMaxMax_;

	private SeekBar seekBarMin_;
	private String seekBarMinText_ = "error";
	private int seekBarMinMin_;
	private int seekBarMinMax_;

	private LinearLayout layout_;
	private long userSelection_;

	public SpriteOptionChooserPreference(Context context, AttributeSet attrs) {
		super(context, attrs);
		initPreference(context, attrs);
	}

	public SpriteOptionChooserPreference(Context context, AttributeSet attrs,
			int defStyle) {
		super(context, attrs, defStyle);
		initPreference(context, attrs);
	}

	private void initPreference(Context context, AttributeSet attrs) {

		TypedArray a = getContext().obtainStyledAttributes(attrs,
				R.styleable.SpriteOptionChooser);

		checkBoxText_ = a
				.getString(R.styleable.SpriteOptionChooser_checkBoxText);

		seekBarText_ = a.getString(R.styleable.SpriteOptionChooser_seekBarText);
		seekBarOneMin_ = a
				.getInt(R.styleable.SpriteOptionChooser_seekBarMin, 1);
		seekBarOneMax_ = a.getInt(R.styleable.SpriteOptionChooser_seekBarMax,
				50);

		seekBarMaxText_ = a
				.getString(R.styleable.SpriteOptionChooser_seekBarMaxText);
		seekBarMaxMin_ = a.getInt(
				R.styleable.SpriteOptionChooser_seekBarMaxMin, 1);
		seekBarMaxMax_ = a.getInt(
				R.styleable.SpriteOptionChooser_seekBarMaxMax, 50);

		seekBarMinText_ = a
				.getString(R.styleable.SpriteOptionChooser_seekBarMinText);
		seekBarMinMin_ = a.getInt(
				R.styleable.SpriteOptionChooser_seekBarMinMin, 1);
		seekBarMinMax_ = a.getInt(
				R.styleable.SpriteOptionChooser_seekBarMinMax, 50);

		a.recycle();
	}

	@Override
	protected View onCreateView(ViewGroup parent) {

		layout_ = null;

		try {
			LayoutInflater mInflater = (LayoutInflater) getContext()
					.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

			layout_ = (LinearLayout) mInflater.inflate(
					R.layout.sprite_option_chooser_preference, parent, false);
		} catch (Exception e) {
			Log.e(TAG, "Error creating preference", e);
		}

		((TextView) layout_.findViewById(R.id.sprite_option_check_box_title))
				.setText(checkBoxText_);
		((TextView) layout_.findViewById(R.id.sprite_option_title))
				.setText(seekBarText_);
		((TextView) layout_.findViewById(R.id.max_sprite_option_title))
				.setText(seekBarMaxText_);
		((TextView) layout_.findViewById(R.id.min_sprite_option_title))
				.setText(seekBarMinText_);

		randomCheckBox_ = (CheckBox) layout_
				.findViewById(R.id.sprite_option_check_box);
		seekBar_ = (SeekBar) layout_.findViewById(R.id.sprite_option_seek_bar);
		seekBarMax_ = (SeekBar) layout_
				.findViewById(R.id.max_sprite_option_seek_bar);
		seekBarMin_ = (SeekBar) layout_
				.findViewById(R.id.min_sprite_option_seek_bar);

		seekBar_.setMax(seekBarOneMax_ - seekBarOneMin_);
		seekBarMax_.setMax(seekBarMaxMax_ - seekBarMaxMin_);
		seekBarMin_.setMax(seekBarMinMax_ - seekBarMinMin_);

		if (userSelection_ == 0l) {
			userSelection_ = 0xa0f05;
		}
		Log.v(TAG, "Load: " + Long.toHexString(userSelection_));
		randomCheckBox_.setChecked(((userSelection_ >>> 24) & 0x1) == 1);
		seekBar_.setProgress((int) ((userSelection_ >>> 16) & 0xFF) - 1);
		seekBarMax_.setProgress((int) ((userSelection_ >>> 8) & 0xFF) - 1);
		seekBarMin_.setProgress((int) (userSelection_ & 0xFF) - 1);

		seekBar_.setOnSeekBarChangeListener(this);
		seekBarMax_.setOnSeekBarChangeListener(this);
		seekBarMin_.setOnSeekBarChangeListener(this);
		randomCheckBox_.setOnCheckedChangeListener(this);

		updateView();
		return layout_;
	}

	public void onProgressChanged(SeekBar seekBar, int progress,
			boolean fromUser) {

		if (seekBarMax_.getProgress() == 0) {
			seekBarMax_.setProgress(1);
		}

		if (seekBarMin_.getProgress() >= seekBarMax_.getProgress()) {
			seekBarMin_.setProgress(seekBarMax_.getProgress() - 1);
		}

		updateView();
	}

	public void onStartTrackingTouch(SeekBar seekBar) {
		// not used
	}

	public void onStopTrackingTouch(SeekBar seekBar) {
		packAndPersist();
	}

	public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
		updateView();
		packAndPersist();
	}

	private void updateView() {

		((TextView) layout_.findViewById(R.id.sprite_option_seek_bar_value))
				.setText(String.valueOf(seekBar_.getProgress() + seekBarOneMin_));

		((TextView) layout_.findViewById(R.id.max_sprite_option_seek_bar_value))
				.setText(String.valueOf(seekBarMax_.getProgress()
						+ seekBarMaxMin_));

		((TextView) layout_.findViewById(R.id.min_sprite_option_seek_bar_value))
				.setText(String.valueOf(seekBarMin_.getProgress()
						+ seekBarMinMin_));

		if (randomCheckBox_.isChecked()) {
			((RelativeLayout) layout_.findViewById(R.id.sprite_option_cont))
					.setVisibility(View.GONE);
			((RelativeLayout) layout_.findViewById(R.id.min_sprite_option_cont))
					.setVisibility(View.VISIBLE);
			((RelativeLayout) layout_.findViewById(R.id.max_sprite_option_cont))
					.setVisibility(View.VISIBLE);
		} else {
			((RelativeLayout) layout_.findViewById(R.id.sprite_option_cont))
					.setVisibility(View.VISIBLE);
			((RelativeLayout) layout_.findViewById(R.id.min_sprite_option_cont))
					.setVisibility(View.GONE);
			((RelativeLayout) layout_.findViewById(R.id.max_sprite_option_cont))
					.setVisibility(View.GONE);
		}

		layout_.invalidate();
	}

	private void packAndPersist() {

		long temp = ((((randomCheckBox_.isChecked() ? 0x1 : 0x0) & 0x1) << 24)
				| ((((seekBar_.getProgress() + seekBarOneMin_) & 0xFF) << 16))
				| ((((seekBarMax_.getProgress() + seekBarMaxMin_) & 0xFF) << 8))
				| (((seekBarMin_.getProgress() + seekBarMinMin_) & 0xFF)));

		if (!callChangeListener(temp)) {
			return;
		}

		Log.v(TAG, "Save: " + Long.toHexString(temp));
		userSelection_ = temp;
		persistLong(userSelection_);
		notifyChanged();
	}
	
	@Override
	protected void onSetInitialValue(boolean restoreValue, Object defaultValue) {

		if (restoreValue) {
			userSelection_ = getPersistedLong(userSelection_);
		} else {
			long temp = 0xa0f05;
			persistLong(temp);
			userSelection_ = temp;
		}
	}

}
